using System;
using System.Collections;
using System.Collections.Generic;
using Unity.Collections;
using Unity.Entities;
using Unity.Mathematics;
using Unity.Mathematics.Geometry;

namespace LS
{
    public struct TransformState
    {
        public float3 Scale;
        public float3 Position;
        public quaternion Rotation;
        public float3 Right;
        public float3 Up;
        public float3 Forward;
    }

    public struct PlayerInputState
    {
        public bool IsPressed;
        public Unity.Physics.RaycastInput RaycastInputFromCamera;
    }

    public struct RaycastResultResult
    {
        public bool HasResult;
        public Unity.Physics.RaycastHit RaycastResult;
    }

    public struct SelectionInputState
    {

    }

    public struct FrustumBounds: IEnumerable,IEnumerable<Plane>
    {
        public Plane FrustumPlane1;
        public Plane FrustumPlane2;
        public Plane FrustumPlane3;
        public Plane FrustumPlane4;
        public Plane FrustumPlane5;
        public Plane FrustumPlane6;

        public Plane this[int index]
        {
            get
            {
                switch (index)
                {
                    case 0: return this.FrustumPlane1;
                    case 1: return this.FrustumPlane2;
                    case 2: return this.FrustumPlane3;
                    case 3: return this.FrustumPlane4;
                    case 4: return this.FrustumPlane5;
                    case 5: return this.FrustumPlane6;
                    default:
                        throw new IndexOutOfRangeException($"index: {index.ToString()}");
                }
            }

            set
            {
                switch (index)
                {
                    case 0: this.FrustumPlane1 = value; break;
                    case 1: this.FrustumPlane2 = value; break;
                    case 2: this.FrustumPlane3 = value; break;
                    case 3: this.FrustumPlane4 = value; break;
                    case 4: this.FrustumPlane5 = value; break;
                    case 5: this.FrustumPlane6 = value; break;
                    default:
                        throw new IndexOutOfRangeException($"index: {index.ToString()}");
                }
            }
        }

        public IEnumerator GetEnumerator()
        {
            for (int i = 0; i < 6; i++)
            {
                yield return this[i];
            }
        }

        IEnumerator<Plane> IEnumerable<Plane>.GetEnumerator()
        {
            for (int i = 0; i < 6; i++)
            {
                yield return this[i];
            }
        }
    }

    public struct RTSSelectionStateComponentData : IComponentData
    {
        public TransformState CameraTransform;

        public PlayerInputState LeftClickInput;
        public RaycastResultResult LeftRaycastResult;

        public PlayerInputState RightClickInput;
        public RaycastResultResult RightRaycastResult;

        public InputPhase SelectionPhase;
        public bool SelectionPressed;
        public bool HasSelectionResult;
        public float4x4 ProjectionFromStartToCurrent;
        public FrustumBounds FrustumBounds;
    }
}
